package com.boot.config;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Redis 版 Token 管理器：支持主动登出与 token 有效性检查
 * key: "auth:token:{token}" → value: userId
 * 同时设置过期时间自动清理
 */
@Component
public class TokenStore {

    private final StringRedisTemplate redisTemplate;
    private static final String TOKEN_PREFIX = "auth:token:";           // auth:token:{token}
    private static final String USER_TOKENS_PREFIX = "auth:tokens:user:"; // auth:tokens:user:{userId}
    private static final long EXPIRATION_HOURS = 2L;

    public TokenStore(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 保存 token 并绑定用户 ID，同时维护反向索引
     */
    public void saveToken(String token, Long userId) {
        String tokenKey = TOKEN_PREFIX + token;
        String userTokensKey = USER_TOKENS_PREFIX + userId;

        // 写入 token -> userId 映射
        redisTemplate.opsForValue().set(tokenKey, userId.toString(), EXPIRATION_HOURS, TimeUnit.HOURS);

        // 加入用户 token 集合
        redisTemplate.opsForSet().add(userTokensKey, token);

        // 设置集合过期时间（与 token 一致）
        redisTemplate.expire(userTokensKey, EXPIRATION_HOURS, TimeUnit.HOURS);
    }

    /**
     * 移除单个 token（登出）
     */
    public void removeToken(String token) {
        if (token == null || token.trim().isEmpty()) return;

        String key = TOKEN_PREFIX + token;
        String userIdStr = redisTemplate.opsForValue().get(key);
        if (userIdStr != null) {
            // 删除正向 key
            redisTemplate.delete(key);
            // 从用户 token 集合中移除
            redisTemplate.opsForSet().remove(USER_TOKENS_PREFIX + userIdStr, token);
        }
    }

    /**
     * 强制下线：清除某个用户的全部 token
     */
    public void revokeAllTokensForUser(Long userId) {
        if (userId == null) return;

        String userTokensKey = USER_TOKENS_PREFIX + userId;
        Set<String> tokens = redisTemplate.opsForSet().members(userTokensKey);
        if (tokens != null && !tokens.isEmpty()) {
            // 构造所有 token 的完整 key
            Set<String> fullKeys = tokens.stream()
                    .map(TOKEN_PREFIX::concat)
                    .collect(java.util.stream.Collectors.toSet());
            redisTemplate.delete(fullKeys);         // 删除 token 记录
            redisTemplate.delete(userTokensKey);   // 删除集合本身
        }
    }

    /**
     * 检查 token 是否有效
     */
    public boolean isValid(String token) {
        if (token == null || token.trim().isEmpty()) return false;
        return Boolean.TRUE.equals(redisTemplate.hasKey(TOKEN_PREFIX + token));
    }

    /**
     * 根据 token 获取 userId
     */
    public Long getUserId(String token) {
        if (token == null || token.trim().isEmpty()) return null;
        String value = redisTemplate.opsForValue().get(TOKEN_PREFIX + token);
        return value != null ? Long.valueOf(value) : null;
    }

    /**
     * 获取用户当前有效的 token 数量（可用于判断登录设备数）
     */
    public long getTokenCountForUser(Long userId) {
        String key = USER_TOKENS_PREFIX + userId;
        Long size = redisTemplate.opsForSet().size(key);
        return size == null ? 0 : size;
    }
}
